"""
信号确认引擎
负责协调各个验证器，进行多重确认
"""
import logging
import numpy as np
from typing import Dict, Tuple, List
from collections import defaultdict

from .base import SignalValidator, ValidationContext, ValidationResult
from .validators import (
    ConsecutiveTimeValidator,
    VolumeReliabilityValidator,
    PriceTrendValidator
)

logger = logging.getLogger('SignalConfirmationEngine')


class SignalConfirmationEngine:
    """
    信号确认引擎（门面模式）
    负责管理验证器、执行验证流程、收集统计数据
    """
    
    def __init__(self, config: Dict = None):
        """
        Args:
            config: 配置字典，如果为None则使用默认配置
        """
        # 验证器注册表
        self.validators: Dict[str, SignalValidator] = {}
        
        # 配置表：不同敏感度需要的验证器组合
        self.validation_rules = config or self._get_default_rules()
        
        # 统计数据
        self.stats = {
            'total_signals': 0,
            'filtered_signals': 0,
            'confirmed_signals': 0,
            'filter_reasons': defaultdict(int),
            'validator_stats': defaultdict(lambda: {'passed': 0, 'failed': 0})
        }
        
        # 注册默认验证器
        self._register_default_validators()
    
    def _get_default_rules(self) -> Dict:
        """获取默认验证规则"""
        return {
            'high': {
                'required_validators': ['consecutive', 'volume', 'price'],
                'min_confirmations': 3,
                'min_confidence': 0.7
            },
            'medium': {
                'required_validators': ['consecutive', 'volume'],
                'min_confirmations': 2,
                'min_confidence': 0.6
            },
            'low': {
                'required_validators': ['consecutive'],
                'min_confirmations': 1,
                'min_confidence': 0.5
            },
            'normal': {
                'required_validators': [],
                'min_confirmations': 0,
                'min_confidence': 0.0
            }
        }
    
    def _register_default_validators(self):
        """注册默认验证器"""
        self.register_validator('consecutive', ConsecutiveTimeValidator())
        self.register_validator('volume', VolumeReliabilityValidator())
        self.register_validator('price', PriceTrendValidator())
        logger.info("默认验证器注册完成")
    
    def register_validator(self, name: str, validator: SignalValidator):
        """
        注册验证器（支持扩展）
        
        Args:
            name: 验证器标识
            validator: 验证器实例
        """
        self.validators[name] = validator
        logger.debug(f"注册验证器: {name} - {validator.get_name()}")
    
    def validate_signal(self, context: ValidationContext) -> Tuple[bool, str]:
        """
        验证交易信号
        
        Args:
            context: 验证上下文
            
        Returns:
            Tuple[bool, str]: (是否通过, 详细信息)
        """
        self.stats['total_signals'] += 1
        
        # 止损检查已移至回测系统独立处理（优先级1，每分钟/每天检查）
        # 信号验证系统只负责验证策略信号的可靠性
        
        # 获取敏感度对应的验证规则
        sensitivity = context.sensitivity
        rules = self.validation_rules.get(sensitivity, self.validation_rules['normal'])
        
        # 如果是正常时段，直接通过
        if sensitivity == 'normal':
            self.stats['confirmed_signals'] += 1
            return True, f"{context.sell_reason} | 正常时段直接执行"
        
        # 执行验证
        results = self._run_validators(context, rules['required_validators'])
        
        # 统计通过的验证器数量
        passed_count = sum(1 for r in results if r.passed)
        avg_confidence = np.mean([r.confidence for r in results]) if results else 0.0
        
        # 判断是否通过
        confirmed = (
            passed_count >= rules['min_confirmations'] and
            avg_confidence >= rules['min_confidence']
        )
        
        # 构建详细信息
        details = self._build_details(
            context, results, passed_count, 
            rules['min_confirmations'], avg_confidence
        )
        
        # 更新统计
        if confirmed:
            self.stats['confirmed_signals'] += 1
        else:
            self.stats['filtered_signals'] += 1
            self.stats['filter_reasons'][sensitivity] += 1
            # 不在这里输出日志，由回测系统统一输出（避免重复）
        
        return confirmed, details
    
    def _run_validators(self, 
                       context: ValidationContext, 
                       validator_names: List[str]) -> List[ValidationResult]:
        """
        运行指定的验证器
        
        Args:
            context: 验证上下文
            validator_names: 验证器名称列表
            
        Returns:
            List[ValidationResult]: 验证结果列表
        """
        results = []
        for validator_name in validator_names:
            validator = self.validators.get(validator_name)
            if validator:
                try:
                    result = validator.validate(context)
                    results.append(result)
                    
                    # 更新验证器统计
                    status = 'passed' if result.passed else 'failed'
                    self.stats['validator_stats'][validator_name][status] += 1
                    
                except Exception as e:
                    logger.error(f"验证器 {validator_name} 执行异常: {e}")
                    results.append(ValidationResult(
                        passed=False,
                        validator_name=validator_name,
                        details=f"执行异常: {str(e)}",
                        confidence=0.0
                    ))
        return results
    
    def _build_details(self, 
                      context: ValidationContext, 
                      results: List[ValidationResult],
                      passed_count: int, 
                      required: int, 
                      confidence: float) -> str:
        """
        构建详细信息字符串
        
        Args:
            context: 验证上下文
            results: 验证结果列表
            passed_count: 通过的验证器数量
            required: 需要的验证器数量
            confidence: 平均置信度
            
        Returns:
            str: 详细信息
        """
        details_parts = [
            f"{context.sell_reason}",
            f"{context.sensitivity}敏感度",
            f"{passed_count}/{required}确认",
            f"置信度:{confidence:.2f}"
        ]
        
        # 添加每个验证器的结果
        for result in results:
            status = "🟢" if result.passed else "🔴"
            details_parts.append(f"{status}{result.validator_name}({result.details})")
        
        return " | ".join(details_parts)
    
    def get_statistics(self) -> Dict:
        """
        获取统计信息
        
        Returns:
            Dict: 统计数据
        """
        filter_rate = (self.stats['filtered_signals'] / 
                      max(self.stats['total_signals'], 1))
        
        return {
            'total_signals': self.stats['total_signals'],
            'confirmed_signals': self.stats['confirmed_signals'],
            'filtered_signals': self.stats['filtered_signals'],
            'filter_rate': filter_rate,
            'filter_reasons': dict(self.stats['filter_reasons']),
            'validator_stats': dict(self.stats['validator_stats'])
        }
    
    def reset_statistics(self):
        """重置统计信息"""
        self.stats = {
            'total_signals': 0,
            'filtered_signals': 0,
            'confirmed_signals': 0,
            'filter_reasons': defaultdict(int),
            'validator_stats': defaultdict(lambda: {'passed': 0, 'failed': 0})
        }
        logger.info("统计信息已重置")
    
    def print_statistics(self):
        """打印统计信息"""
        stats = self.get_statistics()
        
        print(f"\n{'='*60}")
        print(f"📊 信号验证统计")
        print(f"{'='*60}")
        print(f"总信号数: {stats['total_signals']}")
        print(f"确认信号: {stats['confirmed_signals']}")
        print(f"过滤信号: {stats['filtered_signals']}")
        print(f"过滤率: {stats['filter_rate']:.2%}")
        
        if stats['filter_reasons']:
            print(f"\n各敏感度时段过滤次数:")
            for sensitivity, count in stats['filter_reasons'].items():
                print(f"  {sensitivity}: {count}次")
        
        if stats['validator_stats']:
            print(f"\n各验证器统计:")
            for validator_name, stat in stats['validator_stats'].items():
                total = stat['passed'] + stat['failed']
                pass_rate = stat['passed'] / total if total > 0 else 0
                print(f"  {validator_name}: 通过{stat['passed']}次 | "
                     f"未通过{stat['failed']}次 | 通过率{pass_rate:.1%}")
        
        print(f"{'='*60}\n")

